<?php
/**
 * NetBiz Framework
 * Copyright (C) 20009 - 2010 NetBiz
 * 
 * All rights reserved.
 */
 
require_once 'Log.php';

class FRM_Log {
	
	/*const EMERG = PEAR_LOG_EMERG;
	const ALERT = PEAR_LOG_ALERT;
	const CRIT = PEAR_LOG_CRIT;*/
	const ERR = PEAR_LOG_ERR;
	const WARNING = PEAR_LOG_WARNING;
	const NOTICE = PEAR_LOG_NOTICE;
	const INFO = PEAR_LOG_INFO;
	const DEBUG = PEAR_LOG_DEBUG;


	protected static $log_facilities = null;

	protected $_logger = array(
			/*PEAR_LOG_EMERG => array(),
			PEAR_LOG_ALERT => array(),
			PEAR_LOG_CRIT => array(),*/
			PEAR_LOG_ERR => array(),
			PEAR_LOG_WARNING => array(),
			PEAR_LOG_NOTICE => array(),
			PEAR_LOG_INFO => array(),
			PEAR_LOG_DEBUG => array(),
		);

	static protected function initialize()
	{
		self::$log_facilities = array(
			'composite' => array(),
			'console' => array(),
			'display' => array(),
			'error_log' => array(),
			'file' => array('mode' => 0664, 'dirmode' => 0775),
			'firebug' => array('buffering' => TRUE),
			'mail' => array('subject' => '[LOG] '.FRM_Config::get('APPLICATION','NAME')),
			'null' => array(),
			// 'mdb2' => array('name' => '', 'conf' => array()), TODO
			// 'db' => array('name' => '', 'conf' => array()),  TODO
			// 'sqlite' => array('name' => '', 'conf' => array()),  TODO
			'win' => array(),
			'syslog' => array() );
	}
	
	static protected function factory($facility,$name)
	{
		if (!isset(self::$log_facilities[$facility])) { $facility = 'null'; }
		
		// Try to include our own FRM class, if it fails, call the standard factory instead
		$class = 'FRM_Log_' . ucfirst(strtolower($facility));
		if (class_exists($class))
		{
			return new $class(
				$name,
				FRM_Config::get('APPLICATION','NAME'),
				self::$log_facilities[$facility],
				PEAR_LOG_DEBUG );
		}
		else
		{
			return Log::factory(
				$facility,
				$name,
				FRM_Config::get('APPLICATION','NAME'),
				self::$log_facilities[$facility],
				PEAR_LOG_DEBUG );
		}
	}
	
	function __construct()
	{
		if (self::$log_facilities == null)
		{
			self::initialize();
		}
	}

	public function addLogger($facility,$param = '',$levels = null,$decorator = null)
	{
		// Meaning all levels
		if (is_null($levels))
		{
			$levels = array(
				/*PEAR_LOG_EMERG,
				PEAR_LOG_ALERT,
				PEAR_LOG_CRIT,*/
				PEAR_LOG_ERR,
				PEAR_LOG_WARNING,
				PEAR_LOG_NOTICE,
				PEAR_LOG_INFO,
				PEAR_LOG_DEBUG,);
		}
		
		if (!is_array($levels))
		{
			$levels = array($levels);
		}
		
		switch($facility)
		{
			case 'syslog' :
				$param = LOG_LOCAL0;
				break;
			case 'mail' :
			case 'file' :
				break;
			default :
				$param = '';		
		}
		
		$log = self::factory($facility,$param);
		if (!($decorator instanceof FRM_Log_Decorator))
		{
			$decorator = new FRM_Log_DecoratorStandard();
		}
		
		foreach($levels as $level)
		{
			if (isset($this->_logger[$level]))
			{
				$this->_logger[$level][] = array('l' => $log, 'd' => $decorator);
			}
		}
	}

	public function log($message, $priority)
	{
		$pstring = $this->priorityToString($priority);

		if ($pstring !== FALSE)
		{
			if (FRM_Config::get('LOG','ENABLE_'.strtoupper($pstring)))
			{
				foreach($this->_logger[$priority] as $log)
				{
					$class = get_class($log['d']);
					$m = new $class($message,$priority);
					$log['l']->log($m,$priority);
				}
				
				return TRUE;
			}
			
			return FALSE;
		}
		else
		{
			throw new FRM_Exception("Unknown priority ($priority) when logging message '$message'",FRM_Exception::PARAMETER);
		}
	}

	/**
	* @see Log::emerg
	*/
	/*function emerg($message)
	{
		$this->log($message,PEAR_LOG_EMERG);
	}*/

	/**
	* @see Log::alert
	*/
	/*function alert($message)
	{
		$this->log($message,PEAR_LOG_ALERT);
	}*/

	/**
	* @see Log::crit
	*/
	/*function crit($message)
	{
		$this->log($message,PEAR_LOG_CRIT);
	}*/

	/**
	* @see Log::err
	*/
	public function err($message)
	{
		$this->log($message,PEAR_LOG_ERR);
	}

	/**
	* @see Log::warning
	*/
	public function warning($message)
	{
		$this->log($message,PEAR_LOG_WARNING);
	}

	/**
	* @see Log::notice
	*/
	public function notice($message)
	{
		$this->log($message,PEAR_LOG_NOTICE);
	}

	/**
	* @see Log::notice
	*/
	public function info($message)
	{
		$this->log($message,PEAR_LOG_INFO);
	}

	/**
	* @see Log::debug
	*/
	public function debug($message)
	{
		$this->log($message,PEAR_LOG_DEBUG);
	}

	public function priorityToString($priority)
	{
		static $strings = array(
			/*PEAR_LOG_EMERG   => 'emerg',
			PEAR_LOG_ALERT   => 'alert',
			PEAR_LOG_CRIT    => 'crit',*/
			PEAR_LOG_ERR     => 'err',
			PEAR_LOG_WARNING => 'warning',
			PEAR_LOG_NOTICE  => 'notice',
			PEAR_LOG_INFO    => 'info',
			PEAR_LOG_DEBUG   => 'debug'
		);
	
		return isset($strings[$priority])?$strings[$priority]:FALSE;
	}
}